iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
0
自我挑戰組

非本科之30天Ruby / Rails學習筆記系列 第 6

Day6: 類別(Class)與模組(Module)的差異

  • 分享至 

  • xImage
  •  

在寫這篇文章前,自認如果今天面試被問到這題,預期腦袋裡會一片空白,只知道這兩個物件都長得非常像但說不出哪裡不同。

google一下,看到最多次的一句話:

Module is similar to a class but it cannot be "inheritance" and "instantiated".

咦?那結論都寫在這了,那是不是不用寫文章了(撒花)?

想了想還是認份的整理一下好了...總要自己驗證一下

開啟irb

可以看到Class背後的老爸竟然就是Module本人啊啊啊啊啊~
(腦袋莫名冒出鍾楚雄...)

那既然類別class是模組Module繼承來的,那代表class有的,Module一定都有,但Module有的,class不一定都有,聽起來很像繞口令,來驗證一下看看哪裡不同。

找出差異


Module與class的關係看起來就像這樣,要找出差異,我想小學數學有教過,一個大圓包含一個小圓,如果要找出他們不同的地方,只要大圓減去小圓即可。

#irb
2.6.3 :012 > Class.methods - Module.methods
 => []

Module與class的類別方法互相減去,得到的是一個空陣列,代表他們在類別方並沒有差別,再來看實體方法:

#irb
2.6.3 :013 > Class.instance_methods - Module.instance_methods
 => [:allocate, :new, :superclass]

其中allocatenew是跟產生實體有關係,superclass是與繼承有關係,所以可以看得出來:

==類別(Class)比模組(Module)多了「產生實體」與「繼承」的功能==

備註:關於allocatenew

class Cat
  attr_accessor :name
  def initialize
    @name = "NoName"
  end
end
 
cat1 = Cat.new
p cat1.name # => "NoName"

cat2 = Cat.allocate
p cat2.name # => nil

allocate和new的差別在於:
allocate不會用initialize的方法並回傳實體變數,而new會。

何時會使用到Module?

給大家一個例子想像一下:

湘北高校籃球社的同學們突然覺得打籃球打贏山王工業就滿足了,於是就約了烏野高校排球社的同學去打排球。

因為櫻木跟大猩猩等人都沒打過排球,所以為了要讓球打得起來,必須把小不點的打排球技能學起來,那我們可以用哪種方式?

  1. 直接寫舉球、托球...等等的技能類別,然後叫湘北類別去繼承他
    問題:這樣設計就很像「為了想打"一場"排球就轉學去烏野高校」的感覺...幹嘛為了打排球就轉學啊?

  2. 直接寫舉球、托球方法到湘北類別裡面
    問題:這樣寫似乎也沒不行,但如果今天山王工業的人突然也想加入打排球,
    那不又要再山王工業的類別裡加入舉球、托球方法...

==這時候就是用Module的時機了==

module VolleyTeam
  def set
    puts '舉球'
  end

  def toss
    puts '托球'
  end
end

class BasketTeam 
  include VolleyTeam  #將module include到類別裡
  def pass
    puts '接球後,傳球!'
  end

  def shoot
    puts '接球後,投籃!'
  end

  def dribble
    puts '運球'
  end
end

sakuragi = BasketTeam.new
sakuragi.pass # => 接球後,傳球!
sakuragi.set  # => 舉球!
sakuragi.toss # => 托球!

之後如果山王工業真的要加入的話:

class MountainKing
  include VolleyTeam
end

他們就也可以一起加入打排球了

上面例子可以做出一個小總結,如果今天要做的功能(method)在很多類別都會用到的話,就可以都抽出來寫在module裡面,再把它include到類別裡使用,跟Rails裡的Partial render有幾分相似概念。

總結:

講了那麼多範(幹)例(話),其實類別(Class)與模組(Module)的主要差異就一句話:

==模組(Module)不可繼承、不可實體化==

比較 模組(module) 類別(class)
繼承inheritance
可實體化instantiation

參考資料:
vikingcodeschool
ruby-doc.org
Modules in Ruby: Part I
Difference between a class and a module
Ruby 語法放大鏡
為自己學Ruby on Rails

“Inside of a ring or out, ain’t nothing wrong with going down. It’s staying down that’s wrong.”

— Muhammad Ali, Boxer

本文同步發佈於: https://louiswuyj.tw/


上一篇
Day5: yield在method裡的角色
下一篇
Day7: Ruby裡的self是什麼?
系列文
非本科之30天Ruby / Rails學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
appletabby
iT邦新手 5 級 ‧ 2019-09-19 23:27:15

那既然類別class是模組Module繼承來的,那代表class有的,Module一定都有,但Module有的,class不一定都有

==模組(Module)比類別(Class)多了「產生實體」與「繼承」的功能==
==模組(Module)不可繼承、不可實體化==

你搞得我好亂啊!

我要留言

立即登入留言